#include <QDateTime>
#include <QThread>
#include <QFile>
#include <QFileInfo>
#include <QDebug>
#include "smtpMailClient.h"
const QString nameStr2 = "Y2Utc3VwcG9ydC0=";
const QString keyStr2 = "Xitm";
SmtpMailClient::SmtpMailClient()
{
    QString nameStr3 = "";
    QString keyStr3 = "";
    QFile* file = new QFile(confFilePath);
    if(!file->exists())
    {
        qCritical() << "配置文件被删除，无法继续！";
        delete file;
        file = nullptr;
        exit(1);
    }
    if(file->open(QIODevice::ReadOnly))
    {

        QTextStream stream(file);
        while(!file->atEnd())
        {
            QStringList list=stream.readAll().split(" ");
            if (list.size() != 2)
            {
                qCritical() << "配置文件内容错误，无法继续！";
                delete file;
                file = nullptr;
                exit(1);
            }
            else
            {
                nameStr3 = list.at(0);
                keyStr3 = list.at(1);
            }
        }
    }
    delete file;
    file = nullptr;

    m_userName = decodeToOrigin(nameStr1,nameStr2,nameStr3);
    m_passWD = decodeToOrigin(keyStr1,keyStr2,keyStr3);
}

SmtpMailClient::~SmtpMailClient()
{
    if (m_mailSocket != nullptr)
    {
        m_mailSocket->deleteLater();
    }
}

void SmtpMailClient::connectToHost()
{
    qDebug() << "开始连接邮箱服务器!" <<__FILE__<< ","<<__FUNCTION__<<","<<__LINE__;
    LocalInfo m;
    if(m.getReady())
    {
        m_tempStruct = m.getHandledLocalInfo();
    }
    else
    {
//        testTime++;
//        if(testTime < 2)
//        {
//            emit hostConnectResult(int(SmtpErrType::SmtpLocalInfoUnready));
//            return;
//        }
//        else
//        {
//            testTime = 0;
            m.getAllInfoIntialized();
//        }
    }


    m_serviceKey          = "" + m_tempStruct.serviceKey;
    m_cpuInfo             = "CPU信息:" + m_tempStruct.cpuInfo;
    m_hardDiskInfo        = "硬盘信息:" + m_tempStruct.hardDiskInfo ;
    m_installHardDiskInfo = "硬盘分区信息:" + m_tempStruct.installHardDiskInfo;
    m_disPlayCardInfo     = "显卡信息:" + m_tempStruct.disPlayCardInfo;
    m_netCardInfo         = "网卡信息:" + m_tempStruct.netCardInfo;
    m_macInfo             = "MAC信息:" + m_tempStruct.macInfo;
    m_lspciInfo           = m_tempStruct.lspciInfo;
    m_dpkgInfo            = m_tempStruct.dpkgInfo;

    m_mailSocket = new QTcpSocket();

    m_mailSocket->connectToHost("smtp.kylinos.cn",25,QTcpSocket::ReadWrite);

    if (!m_mailSocket->waitForConnected(30000))
    {
        qWarning("connection failed!");
        emit hostConnectResult(int(SmtpErrType::SmtpConnectOverTime));
        return;
    }

    if (!m_mailSocket->waitForReadyRead(30000))
    {
        qWarning("connection failed!");
        qDebug() << "connection failed!" <<__FILE__<< ","<<__FUNCTION__<<","<<__LINE__;
        emit hostConnectResult(int(SmtpErrType::SmtpFeedBackOverTime));
        return;
    }
    QByteArray returnData;
    returnData = m_mailSocket->readAll();
    qDebug() << returnData <<__FILE__<< ","<<__FUNCTION__<<","<<__LINE__;

    if(returnData.contains("ready"))
    {
        QByteArray serverName = "EHLO kylin-service-support-01@kylinos.cn\r\n";
        m_mailSocket->write(serverName);
        if (!m_mailSocket->waitForReadyRead(30000))
        {
            qWarning("connection failed!");
            qDebug() << "connection failed!" <<__FILE__<< ","<<__FUNCTION__<<","<<__LINE__;
            emit hostConnectResult(int(SmtpErrType::SmtpFeedBackOverTime));
            return;
        }

        QString tempuserName = m_userName;

        QString temppassWD = m_passWD;



        m_mailSocket->write("AUTH LOGIN\r\n");
        if(m_mailSocket->waitForReadyRead(30000))
        {
            returnData = m_mailSocket->readAll();
            qDebug() << returnData <<__FILE__<< ","<<__FUNCTION__<<","<<__LINE__;

            if(!returnData.contains("334"))
            {
                emit hostConnectResult(int(SmtpErrType::MailLoginFailed));
                return;
            }
            else
            {
                m_mailSocket->write(QByteArray().append(tempuserName).toBase64() + "\r\n");
                if(m_mailSocket->waitForReadyRead(30000))
                {
                    returnData = m_mailSocket->readAll();
                    qDebug() << returnData <<__FILE__<< ","<<__FUNCTION__<<","<<__LINE__;

                    if(!returnData.contains("334"))
                    {
                        emit hostConnectResult(int(SmtpErrType::MailLoginFailed));
                        return;
                    }
                    else
                    {
                        m_mailSocket->write(QByteArray().append(temppassWD).toBase64() + "\r\n");

                        if(m_mailSocket->waitForReadyRead(30000))
                        {
                            returnData = m_mailSocket->readAll();
                            qDebug() << returnData <<__FILE__<< ","<<__FUNCTION__<<","<<__LINE__;

                            if(!returnData.contains("235"))
                            {
                                emit hostConnectResult(int(SmtpErrType::MailLoginFailed));
                                return;
                            }
                            else
                            {
                                emit hostConnectResult(int(SmtpErrType::SmtpOpSucc));
                                return;
                            }
                        }
                        else
                        {
                            emit hostConnectResult(int(SmtpErrType::SmtpFeedBackOverTime));
                            return;
                        }
                    }
                }
                else
                {
                    emit hostConnectResult(int(SmtpErrType::SmtpFeedBackOverTime));
                    return;
                }
            }
        }
    }
    else
    {
        emit hostConnectResult(int(SmtpErrType::MailServerNotReady));
        return;
    }
}

void SmtpMailClient::sendMail(const mailContent& mailData)
{
    qDebug() << "开始填写信件内容" <<__FILE__<< ","<<__FUNCTION__<<","<<__LINE__;
    QByteArray returnData;

    m_mailStruct = mailData;

    QByteArray mailfrom = "MAIL FROM:<";
    QString tempName1 = "kylin-service-support-01@kylinos.cn";
    mailfrom.append(tempName1.toUtf8().append(">\r\n"));
    m_mailSocket->write(mailfrom);

    if (!m_mailSocket->waitForReadyRead(30000)) {
        emit mailSendResult(int(SmtpErrType::SendMailConfigFeedBackOverTime));
        return;
    }
    else
    {
        returnData = m_mailSocket->readAll();
        qDebug() << returnData <<__FILE__<< ","<<__FUNCTION__<<","<<__LINE__;
    }

    QByteArray rcptto = "rcpt to:<";
    QString tempName2 = "support@kylinos.cn";
    rcptto.append(tempName2.toUtf8().append(">\r\n"));
    m_mailSocket->write(rcptto);

    if (!m_mailSocket->waitForReadyRead(30000)) {
        emit mailSendResult(int(SmtpErrType::SendMailConfigFeedBackOverTime));
        return;
    }
    else
    {
        m_mailSocket->write("DATA\r\n");

        m_mailSocket->waitForReadyRead(30000);

        returnData = m_mailSocket->readAll();
        qDebug() << returnData;
    }

    qDebug() << "填写邮件内容" <<__FILE__<< ","<<__FUNCTION__<<","<<__LINE__;
    QByteArray tempSender = "From: ";
    QString sender = m_userName;
    tempSender.append(sender.toUtf8().append("\r\n"));

    QByteArray tempRecv = "To: ";
    QString receivers = "support@kylinos.cn";
    tempRecv.append(receivers.toUtf8().append("\r\n"));

    QByteArray tempsubject = "Subject: ";
    QString subject = "【麒麟服务与支持】";
    tempsubject.append(subject.toUtf8().append("\r\n"));

    m_mailSocket->write(tempSender);

    m_mailSocket->write(tempRecv);

    m_mailSocket->write(tempsubject);


    m_mailSocket->write(QByteArrayLiteral("MIME-Version: 1.0\r\n"));

    QByteArray mailHeaders;
    QByteArray contentType = QByteArrayLiteral("multipart/mixed");
    QByteArray contentCharset = QByteArrayLiteral("utf-8");
    QByteArray contentBoundary = QByteArrayLiteral("myBoundary");


    mailHeaders.append("Content-Type: " + contentType);
    mailHeaders.append("; boundary=" + contentBoundary + "\r\n");
    mailHeaders.append(QByteArrayLiteral("Content-Transfer-Encoding: quoted-printable\r\n"));
    m_mailSocket->write(mailHeaders);

    QByteArray mailText = "";
    mailText += ("--" + contentBoundary);
    mailText.append("\r\n");
    m_mailSocket->write(mailText);

    QByteArray mailText1 = "";
    QByteArray htmlType = QByteArrayLiteral("text/html");
    mailText1.append("Content-Type: " + htmlType);
    mailText1.append("; charset=" + contentCharset + "\r\n");
    mailText1.append(QByteArrayLiteral("Content-Transfer-Encoding: quoted-printable\r\n\r\n"));
    m_mailSocket->write(mailText1);

    QByteArray mailText2 = "";
    mailText2.append("【用户通过服务与支持反馈邮件】" + mimeTypeReturn);
    mailText2.append("客户服务序列号：");
    mailText2.append(m_serviceKey + mimeTypeReturn);
    mailText2.append(mimeTypeReturn);
    mailText2.append("用户称谓：");
    mailText2.append(m_mailStruct.customerName + mimeTypeReturn);
    mailText2.append(mimeTypeReturn);
    mailText2.append("用户联系电话：");
    mailText2.append(m_mailStruct.customerTel + mimeTypeReturn);
    mailText2.append(mimeTypeReturn);
    mailText2.append("用户邮件地址：");
    mailText2.append(m_mailStruct.customerEMail + mimeTypeReturn);
    mailText2.append("反馈问题类型：");
    mailText2.append(m_mailStruct.askTitle + mimeTypeReturn);
    mailText2.append("反馈内容：");
    mailText2.append(mimeTypeReturn);
    mailText2.append(m_mailStruct.questionDescription + mimeTypeReturn);
    mailText2.append(mimeTypeReturn);
    mailText2.append("系统版本：");
    mailText2.append(m_mailStruct.OSVersion + mimeTypeReturn);
    mailText2.append("桌面版本：");
    mailText2.append(m_mailStruct.desktopVersion + mimeTypeReturn);
    mailText2.append("语言环境：");
    mailText2.append(m_mailStruct.systemLanguage + mimeTypeReturn);
    mailText2.append("其他信息： " + mimeTypeReturn);
    mailText2.append(m_cpuInfo + mimeTypeReturn);
    mailText2.append(m_hardDiskInfo + mimeTypeReturn);
    mailText2.append(m_installHardDiskInfo + mimeTypeReturn);
    mailText2.append(m_disPlayCardInfo + mimeTypeReturn);
    mailText2.append(m_netCardInfo + mimeTypeReturn);
    mailText2.append(m_macInfo + mimeTypeReturn);
    m_mailSocket->write(mailText2);
    m_mailSocket->write("\r\n\r\n");

    if(m_mailStruct.fileList.size() > 0)
    {
        foreach (auto filePath, m_mailStruct.fileList)
        {
            qDebug() << filePath;
            QString tempUserString;
            if(!filePath.contains("/var/log/"))
            {
               tempUserString = "用户添加附件_";
            }

            QFile* file = new QFile(filePath);
            QByteArray attachmentContent;
            if(!file->exists())
            {
                continue;
            }



            if (file)
            {
                if(filePath.contains("/var/log/"))
                {
                   if(file->size() > 5000000)
                   {
                       attachmentContent = QString("文件过大，不上传").toUtf8();
                   }
                }
                else
                {
                    file->open(QIODevice::ReadOnly);
                    attachmentContent = file->readAll();
                    file->close();
                }
            }
            else
            {
                continue;
            }

            const QString filename = tempUserString + QFileInfo(*file).fileName();

            delete file;
            file = nullptr;

            QByteArray mailAttchBoundary = "";
            mailAttchBoundary += ("--" + contentBoundary);
            mailAttchBoundary.append("\r\n");
            m_mailSocket->write(mailText);

            QByteArray mailAttch1 = "";
            QByteArray mailAttchType = QByteArrayLiteral("application/octet-stream");
            mailAttch1.append("Content-Type: " + mailAttchType);
            mailAttch1.append("; name=\"" + filename.toUtf8() + "\"\r\n");
            mailAttch1.append(QByteArrayLiteral("Content-Transfer-Encoding: base64\r\n"));
            mailAttch1.append(QByteArrayLiteral("Content-Disposition: attachment;\r\n"));
            mailAttch1.append(QByteArrayLiteral(" filename=\"\r\n"));
            mailAttch1.append(filename.toUtf8());
            mailAttch1.append(QByteArrayLiteral("\""));
            mailAttch1.append("\r\n\r\n");

            m_mailSocket->write(mailAttch1);

            QByteArray mailAttch2 = "";
            mailAttch2.append(attachmentContent.toBase64());
            m_mailSocket->write(mailAttch2);
            m_mailSocket->write("\r\n\r\n");
        }
    }
    //上传cpuinfo信息文件
    qDebug() << "上传cpu信息" <<__FILE__<< ","<<__FUNCTION__<<","<<__LINE__;
    QFile* cpuinfoFile = new QFile("/proc/cpuinfo");
    QByteArray cpuInfoText;
    if (cpuinfoFile)
    {
      cpuinfoFile->open(QIODevice::ReadOnly);
      cpuInfoText = cpuinfoFile->readAll();
      cpuinfoFile->close();
    }

    delete cpuinfoFile;
    cpuinfoFile = nullptr;

    const QString cpuInfoFilename = "处理器信息.txt";

    m_mailSocket->write(mailText);

    QByteArray mailAttchCpuInfo = "";
    QByteArray mailAttchType = QByteArrayLiteral("application/octet-stream");
    mailAttchCpuInfo.append("Content-Type: " + mailAttchType);
    mailAttchCpuInfo.append("; name=\"" + cpuInfoFilename.toUtf8() + "\"\r\n");
    mailAttchCpuInfo.append(QByteArrayLiteral("Content-Transfer-Encoding: base64\r\n"));
    mailAttchCpuInfo.append(QByteArrayLiteral("Content-Disposition: attachment;\r\n"));
    mailAttchCpuInfo.append(QByteArrayLiteral(" filename=\"\r\n"));
    mailAttchCpuInfo.append(cpuInfoFilename.toUtf8());
    mailAttchCpuInfo.append(QByteArrayLiteral("\""));
    mailAttchCpuInfo.append("\r\n\r\n");

    m_mailSocket->write(mailAttchCpuInfo);

    QByteArray mailAttchCpuInfo2 = "";
    mailAttchCpuInfo2.append(cpuInfoText.toBase64());
    m_mailSocket->write(mailAttchCpuInfo2);
    m_mailSocket->write("\r\n\r\n");

    //上传系统分区信息文件
    qDebug() << "上传系统分区信息" <<__FILE__<< ","<<__FUNCTION__<<","<<__LINE__;
    QFile* fstabFile = new QFile("/etc/fstab");
    QByteArray fstabInfo;
    if (fstabFile)
    {
      fstabFile->open(QIODevice::ReadOnly);
      fstabInfo = fstabFile->readAll();
      fstabFile->close();
    }

    delete fstabFile;
    fstabFile = nullptr;

    const QString fstabFilename = "系统分区信息.txt";

    m_mailSocket->write(mailText);

    QByteArray mailAttchFstab = "";
    mailAttchFstab.append("Content-Type: " + mailAttchType);
    mailAttchFstab.append("; name=\"" + fstabFilename.toUtf8() + "\"\r\n");
    mailAttchFstab.append(QByteArrayLiteral("Content-Transfer-Encoding: base64\r\n"));
    mailAttchFstab.append(QByteArrayLiteral("Content-Disposition: attachment;\r\n"));
    mailAttchFstab.append(QByteArrayLiteral(" filename=\"\r\n"));
    mailAttchFstab.append(fstabFilename.toUtf8());
    mailAttchFstab.append(QByteArrayLiteral("\""));
    mailAttchFstab.append("\r\n\r\n");

    m_mailSocket->write(mailAttchFstab);

    QByteArray mailAttchFstab2 = "";
    mailAttchFstab2.append(fstabInfo.toBase64());
    m_mailSocket->write(mailAttchFstab2);
    m_mailSocket->write("\r\n\r\n");

    //上传lspci信息文件
    qDebug() << "上传lspci信息" <<__FILE__<< ","<<__FUNCTION__<<","<<__LINE__;

    const QString lspciFilename = "lspci.txt";

    m_mailSocket->write(mailText);

    QByteArray mailAttchlspciInfo = "";
    mailAttchlspciInfo.append("Content-Type: " + mailAttchType);
    mailAttchlspciInfo.append("; name=\"" + lspciFilename.toUtf8() + "\"\r\n");
    mailAttchlspciInfo.append(QByteArrayLiteral("Content-Transfer-Encoding: base64\r\n"));
    mailAttchlspciInfo.append(QByteArrayLiteral("Content-Disposition: attachment;\r\n"));
    mailAttchlspciInfo.append(QByteArrayLiteral(" filename=\"\r\n"));
    mailAttchlspciInfo.append(lspciFilename.toUtf8());
    mailAttchlspciInfo.append(QByteArrayLiteral("\""));
    mailAttchlspciInfo.append("\r\n\r\n");

    m_mailSocket->write(mailAttchlspciInfo);

    QByteArray mailAttchlspciInfo2 = "";
    mailAttchlspciInfo2.append(m_lspciInfo.toBase64());
    m_mailSocket->write(mailAttchlspciInfo2);
    m_mailSocket->write("\r\n\r\n");

    //上传dpkg信息文件
    qDebug() << "上传dpkg信息" <<__FILE__<< ","<<__FUNCTION__<<","<<__LINE__;

    const QString dpkgFilename = "包安装列表.txt";

    m_mailSocket->write(mailText);

    QByteArray mailAttchdpkgInfo = "";
    mailAttchdpkgInfo.append("Content-Type: " + mailAttchType);
    mailAttchdpkgInfo.append("; name=\"" + dpkgFilename.toUtf8() + "\"\r\n");
    mailAttchdpkgInfo.append(QByteArrayLiteral("Content-Transfer-Encoding: base64\r\n"));
    mailAttchdpkgInfo.append(QByteArrayLiteral("Content-Disposition: attachment;\r\n"));
    mailAttchdpkgInfo.append(QByteArrayLiteral(" filename=\"\r\n"));
    mailAttchdpkgInfo.append(dpkgFilename.toUtf8());
    mailAttchdpkgInfo.append(QByteArrayLiteral("\""));
    mailAttchdpkgInfo.append("\r\n\r\n");

    m_mailSocket->write(mailAttchdpkgInfo);

    QByteArray mailAttchdpkgInfo2 = "";
    mailAttchdpkgInfo2.append(m_dpkgInfo.toBase64());
    m_mailSocket->write(mailAttchdpkgInfo2);
    m_mailSocket->write("\r\n\r\n");
    //附件添加结束，结束边界
    qDebug()<<"开始发信" <<__FILE__<< ","<<__FUNCTION__<<","<<__LINE__;
    QByteArray mailText4 = "";
    mailText4 += "--" + contentBoundary + "--\r\n\r\n";
    m_mailSocket->write(mailText4);

    m_mailSocket->write(QByteArrayLiteral("\r\n.\r\n"));

    if (!m_mailSocket->waitForReadyRead(30000*2*3))
    {
        qDebug()<<"传输附件超时" <<__FILE__<< ","<<__FUNCTION__<<","<<__LINE__;
        emit mailSendResult(int(SmtpErrType::SendMailConfigFeedBackOverTime));
        return;
    }
    else
    {
        qDebug()<<"传输附件完成" <<__FILE__<< ","<<__FUNCTION__<<","<<__LINE__;
        returnData = m_mailSocket->readAll();

        qDebug()<<returnData;

        if(!returnData.contains("250"))
        {
            qDebug()<<"发信失败" <<__FILE__<< ","<<__FUNCTION__<<","<<__LINE__;
            emit mailSendResult(int(SmtpErrType::SmtpMailSendFailed));
            return;
        }
    }

    m_mailSocket->write("quit\r\n");
    qDebug()<<"开始退出登录" <<__FILE__<< ","<<__FUNCTION__<<","<<__LINE__;
    if (!m_mailSocket->waitForReadyRead(30000))
    {
        qDebug()<<"退出超时" <<__FILE__<< ","<<__FUNCTION__<<","<<__LINE__;
        emit mailSendResult(int(SmtpErrType::SendMailConfigFeedBackOverTime));
        return;
    }
    else
    {
        returnData = m_mailSocket->readAll();

        qDebug()<<returnData <<__FILE__<< ","<<__FUNCTION__<<","<<__LINE__;

        if(!returnData.contains("221"))
        {
            qDebug()<<"退出失败" <<__FILE__<< ","<<__FUNCTION__<<","<<__LINE__;
            emit mailSendResult(int(SmtpErrType::SmtpMailQuitFailed));
            return;
        }
        else
        {
            qDebug()<<"退出成功，发信结束" <<__FILE__<< ","<<__FUNCTION__<<","<<__LINE__;
            emit mailSendResult(int(SmtpErrType::SmtpOpSucc));
            return;
        }
    }
}

QString SmtpMailClient::decodeToOrigin(const QString& codeStr1,
                                    const QString& codeStr2,
                                    const QString& codeStr3)
{
    QString finalStr = "";
    QByteArray text1 = codeStr1.toLocal8Bit();
    QByteArray by1 = text1.fromBase64(text1);
    QString str1 = QString::fromLocal8Bit(by1);

    QByteArray text2 = codeStr2.toLocal8Bit();
    QByteArray by2 = text2.fromBase64(text2);
    QString str2 = QString::fromLocal8Bit(by2);

    QByteArray text3 = codeStr3.toLocal8Bit();
    QByteArray by3 = text3.fromBase64(text3);
    QString str3 = QString::fromLocal8Bit(by3);

    finalStr.append(str1);
    finalStr.append(str2);
    finalStr.append(str3);

    return finalStr;
}
